use crate::{AudioPlayer, CameraPacket, CustomError};
use ffmpeg_sys_next::avdevice_register_all;
use sdl2::Sdl;
use std::{
    sync::{
        atomic::{AtomicBool, Ordering},
        Arc,
    },
    time::Duration,
};
use tokio::sync::{broadcast, Mutex};

pub struct CameraFifo {
    pub audio_in_packet_sender: broadcast::Sender<CameraPacket>,
    pub audio_player_packet_receiver: Arc<Mutex<broadcast::Receiver<CameraPacket>>>,
    pub audio_file_packet_receiver: Arc<Mutex<broadcast::Receiver<CameraPacket>>>,
}

impl CameraFifo {
    pub fn new() -> Self {
        let (audio_in_packet_sender, audio_player_packet_receiver): (
            broadcast::Sender<CameraPacket>,
            broadcast::Receiver<CameraPacket>,
        ) = broadcast::channel(5 * 1024);
        let audio_file_packet_receiver = audio_in_packet_sender.subscribe();

        CameraFifo {
            audio_in_packet_sender,
            audio_player_packet_receiver: Arc::new(Mutex::new(audio_player_packet_receiver)),
            audio_file_packet_receiver: Arc::new(Mutex::new(audio_file_packet_receiver)),
        }
    }
}

pub struct MediaPlayer {
    pub audio_player: AudioPlayer,
    pub sdl: Sdl,
    pub camera_fifo: CameraFifo,
}

impl MediaPlayer {
    pub fn new(audio_short_name: String, audio_url: String, out_audio_file: String) -> Self {
        let sdl = sdl2::init().unwrap();
        let camera_fifo = CameraFifo::new();
        let running: Arc<AtomicBool> = Arc::new(AtomicBool::new(true));
        let r = running.clone();
        // 注册 Ctrl+C 信号处理器
        ctrlc::set_handler(move || {
            println!("Received Ctrl+C signal. Exiting...");
            r.store(false, Ordering::SeqCst);
        })
        .expect("Error setting Ctrl+C handler");

        let audio_player = AudioPlayer::new(audio_short_name, audio_url, out_audio_file, running);

        MediaPlayer {
            audio_player,
            sdl,
            camera_fifo,
        }
    }

    pub async fn init(&self) -> Result<(), CustomError> {
        unsafe {
            avdevice_register_all();
        }
        Ok(())
    }

    pub async fn run(&mut self) -> Result<(), CustomError> {
        self.init().await?;

        self.audio_player.find_input_context().await?;
        self.audio_player.alloc_format_context().await?;
        self.audio_player.open_input().await?;
        self.audio_player.dump_format().await?;
        self.audio_player.stream_index().await?;
        self.audio_player.find_decoder().await?;
        self.audio_player.alloc_codec_context().await?;
        self.audio_player.parameters_to_context().await?;
        self.audio_player.open_avcodec().await?;
        self.audio_player.get_buffer_size().await?;
        self.audio_player.init_swr_context().await?;

        self.audio_player.alloc_out_format_context().await?;
        self.audio_player.alloc_output_context().await?;
        self.audio_player.avio_open().await?;
        self.audio_player.find_encoder().await?;
        self.audio_player.alloc_out_codec_context().await?;
        self.audio_player.open_out_avcodec().await?;
        self.audio_player.new_stream().await?;
        self.audio_player.out_parameters_to_context().await?;
        self.audio_player.write_header().await?;
        //self.audio_player.init_sdl().await?;
        self.audio_player
            .async_read_from_audio(self.camera_fifo.audio_in_packet_sender.clone())
            .await?;
        self.audio_player
            .async_write_data(self.camera_fifo.audio_file_packet_receiver.clone())
            .await?;

        // self.audio_player.async_player_data(self.camera_fifo.audio_player_packet_receiver.clone()).await?;
        // self.audio_player.player(&self.sdl).await?;

        std::thread::sleep(Duration::from_secs(10));

        self.audio_player.close().await?;

        Ok(())
    }
}
